/**
 * 字符串一些常用方法
 * @author	http://www.klstudio.com/post/113.html
 * 2009-3-4 11:10
 */
package com.ibio8.utils{
	/**
	 * 字符串一些常用方法。
	 * 
	 * <p>
	 * 字符串相关的常用的方法，例如判断是否相等、忽略空格等。
	 * </p>
	 * <b>此类原作者 http://www.klstudio.com/post/113.html。</b>
	 */
	public class StringUtil {
		
		/**
		 * 比较指定两个字符是否相等
		 * @param	char1	字符串一
		 * @param	char2	字符串二
		 * @return			是否相等
		 */
		public static function equals(char1:String, char2:String):Boolean {
			return char1 == char2;
		}
		
		/**
		 * 忽略大小字母比较字符是否相等
		 * @param	char1	字符串一
		 * @param	char2	字符串二
		 * @return			是否相等
		 */
		public static function equalsIgnoreCase(char1:String,char2:String):Boolean{
			return char1.toLowerCase() == char2.toLowerCase();
		}
		
		/**
		 * 是否是数值字符串
		 * @param	char	指定字符串
		 * @return			是否是数字
		 */
		public static function isNumber(char:String):Boolean {
			if (!char) {
				return false;
			}
			return !isNaN(Number(char));
		}
		
		/**
		 * 是否为合法 Email
		 * @param	char	指定字符串
		 * @return			是否合法
		 */
		public static function isEmail(char:String):Boolean {
			var pattern:RegExp = /(\w|[_.\-])+@((\w|-)+\.)+\w{2,4}+/;
			return checkChar(char, pattern);
		}
		
		/**
		 * 是否是 Double 型数据
		 * @param	char	指定字符串
		 * @return			是否是 Double 型
		 */
		public static function isDouble(char:String):Boolean {
			var pattern:RegExp = /^[+\-]?\d+(\.\d+)?$/;
			return checkChar(char, pattern);
		}
        
		/**
		 * 是否是整数
		 * @param	char	指定字符串
		 * @return			是否是整数
		 */
		public static function isInteger(char:String):Boolean {
			var pattern:RegExp = /^[-\+]?\d+$/;
			return checkChar(char, pattern);
		}
		
		/**
		 * 是否是英文字符（包括大小写）
		 * @param	char	指定字符串
		 * @return			是否是英文字符
		 */
		public static function isEnglish(char:String):Boolean {
			var pattern:RegExp = /^[A-Za-z]+$/;
			return checkChar(char, pattern);
		}
		
		/**
		 * 是否是中文
		 * @param	char	指定字符串
		 * @return			是否是中文
		 */
		public static function isChinese(char:String):Boolean {
			var pattern:RegExp = /^[\u0391-\uFFE5]+$/;
			return checkChar(char, pattern);
		}
		
		/**
		 * 是否是双字节
		 * @param	char	指定字符串
		 * @return			是否是双字节
		 */
		public static function isDoubleChar(char:String):Boolean {
			var pattern:RegExp = /^[^\x00-\xff]+$/;
            return checkChar(char, pattern);
        }
		
		/**
		 * 是否是 url 地址
		 * @param	char	指定字符串
		 * @return			是否是 url 地址
		 */
        public static function isURL(char:String):Boolean {
			if (!char) {
				return false;
			}
			char = char.toLowerCase();
			var pattern:RegExp = /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/;
            return checkChar(char, pattern);
        }
		
		/**
		 * 是否为空白
		 * @param	char	指定字符串
		 * @return			是否为空白
		 * TODO：需要用正则匹配出多个空格的情况
		 */
		public static function isNullOrEmpty(char:String):Boolean {
			switch (char) {
				case null:
				case "":
				case "\t":
				case "\r":
				case "\n":
				case "\f":
					return true;
                default:
					return false;
			}
		}
		
        /**
		 * 是否包含中文
		 * @param	char	指定字符串
		 * @return			是否包含中文
		 */
        public static function hasChineseChar(char:String):Boolean{
            var pattern:RegExp = /[^\x00-\xff]/;
            return checkChar(char, pattern);
        }
		
		//
		/**
		 * 检测字符长度，判断是否达到指定的长度
		 * @param	char	指定字符串
		 * @param	length	指定的长度
		 * @return			是否达到指定的长度
		 */
		public static function hasAccountChar(char:String, length:uint):Boolean {
			if (!char) {
				return false;
			}
            var pattern:RegExp = new RegExp("^[a-zA-Z0-9][a-zA-Z0-9_-]{0," + length + "}$", "");
            return checkChar(char, pattern);
        }
		
		/**
		 * 转化为 boolean 变量
		 * @param	s
		 * @param	def
		 * @return
		 */
		public static function convertBoolean(char:String, def:Boolean = false):Boolean {
			var result:Boolean;
			//TODO: this should be changed!
			if (isNullOrEmpty(char)) {
				result = def;
			}
			else {
				switch(char.toLowerCase()) {
					case "1":
					case "true":
					case "yes":
						result = true;
						break;
					case "0":
					case "false":
					case "no":
						result = false;
						break;
				}
			}
			return result;
		}
		
		/**
		 * 检测指定字符串是否匹配指定模式
		 * @param	char	指定字符串
		 * @param	pattern	指定模式
		 * @return			是否匹配
		 */
		public static function checkChar(char:String, pattern:RegExp):Boolean {
			if (!char) {
				return false;
			}
			char = trim(char);
			return pattern.test(char);
		}
		
		/**
		 * 去左右空格
		 * @param	char	指定字符串
		 */
		public static function trim(char:String):String {
			if (!char) {
				return null;
			}
			return rtrim(ltrim(char));
		}
		
		/**
		 * 去左空格
		 * @param	char	指定字符串
		 */
		public static function ltrim(char:String):String {
			if (!char) {
				return null;
			}
			var pattern:RegExp = /^\s*/; 
			return char.replace(pattern, "");
		}
        
		/**
		 * 去右空格
		 * @param	char	指定字符串
		 */
		public static function rtrim(char:String):String {
			if (!char) {
				return null;
			}
			var pattern:RegExp = /\s*$/; 
			return char.replace(pattern, "");
		}
		
		/**
		 * 是否为前缀字符串
		 * @param	char	指定字符串
		 * @param	prefix	指定前缀
		 * @return			是否符合
		 */
		public static function beginsWith(char:String, prefix:String):Boolean {
			return (prefix == char.substring(0, prefix.length));
		}
        
		/**
		 * 是否为后缀字符串
		 * @param	char	指定字符串
		 * @param	prefix	指定后缀
		 * @return			是否符合
		 */
        public static function endsWith(char:String, suffix:String):Boolean {
			return (suffix == char.substring(char.length - suffix.length));
		}
        
		/**
		 * 去除指定字符串
		 * @param	char	指定字符串
		 * @param	remove	需要去除的字符串
		 * @return			新的字符串
		 */
        public static function remove(char:String, remove:String):String {
			return replace(char, remove, "");
		}
		
		/**
		 * 字符串替换
		 * @param	char		指定字符串
		 * @param	replace		需要替换的字符串
		 * @param	replaceWith	需要替换的字符串的宽度
		 * @return				新的字符串
		 */
		public static function replace(char:String, replace:String, replaceWith:String):String{
			return char.split(replace).join(replaceWith);
		}
		
		/**
		 * utf16 转 utf8 编码
		 * @param	char	指定字符串
		 * @return			新的字符串
		 */
		public static function utf16to8(char:String):String {
			var out:Array = [];
			var length:uint = char.length;
			for (var i:uint = 0; i < length; i++) {
				var c:int = char.charCodeAt(i);
				if(c >= 0x0001 && c <= 0x007F){
					out[i] = char.charAt(i);
				} else if (c > 0x07FF) {
					out[i] = String.fromCharCode(0xE0 | ((c >> 12) & 0x0F),
												 0x80 | ((c >>  6) & 0x3F),
												 0x80 | ((c >>  0) & 0x3F));
				} else {
					out[i] = String.fromCharCode(0xC0 | ((c >>  6) & 0x1F),
												 0x80 | ((c >>  0) & 0x3F));
				}
			}
			return out.join('');
		}
		
		/**
		 * utf8 转 utf16 编码
		 * @param	char	指定字符串
		 * @return			新的字符串
		 */
        public static function utf8to16(char:String):String {
			var out:Array = [];
			var length:uint = char.length;
			var i:uint = 0;
			var char2:int;
			var char3:int;
			while (i < length) {
				var c:int = char.charCodeAt(i++);
				switch(c >> 4){
					case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
						// 0xxxxxxx
						out[out.length] = char.charAt(i-1);
						break;
					case 12: case 13:
						// 110x xxxx   10xx xxxx
						char2 = char.charCodeAt(i++);
						out[out.length] = String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
						break;
						case 14:
						// 1110 xxxx  10xx xxxx  10xx xxxx
						char2 = char.charCodeAt(i++);
						char3 = char.charCodeAt(i++);
						out[out.length] = String.fromCharCode(((c & 0x0F) << 12) |
							((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
						break;
				}
			}
			return out.join('');
		}
	}
}